package com.urbane.api.config;

import com.urbane.api.services.cart.CartService;
import com.urbane.api.services.inventory.InventoryService;
import com.urbane.api.services.order.OrderService;
import com.urbane.api.services.product.ProductService;
import com.urbane.api.services.promotion.PromotionService;
import com.urbane.api.services.user.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatusCode;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;

@Configuration
public class HttpInterfaceConfig {

    // WebClient 是一个非阻塞、响应式的客户端，用于执行 HTTP 请求。它在 5.0 中引入，提供了 RestTemplate 的替代方案，支持同步、异步和流式场景。
    // WebClient 参考 https://docs.springjava.cn/spring-framework/reference/integration/rest-clients.html#rest-webclient
    @Bean
    public WebClient webClient() {
        return WebClient.builder()
                .baseUrl("https://api.github.com/")
                // 默认情况下，WebClient 对于 4xx 和 5xx HTTP 状态码会抛出 WebClientResponseException。
                // 要自定义此行为，请注册一个响应状态处理程序，该处理程序将应用于通过客户端执行的所有响应
                .defaultStatusHandler(HttpStatusCode::isError, resp -> null)
                .build();
    }

    // 现在您可以创建一个 RestClient 代理，在调用方法时执行请求。
    // 现在，我们可以将客户端代理实例注册为 Spring Bean 或组件，并用它请求 REST 服务。
    @Bean
    public UserService userService(WebClient webClient) {
        WebClient webClient = WebClient.builder().baseUrl("https://api.github.com/").build();
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        return factory.createClient(UserService.class);
    }

    @Bean
    public CartService cartService(WebClient webClient) {
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        return factory.createClient(CartService.class);
    }

    @Bean
    public ProductService productService(WebClient webClient) {
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        return factory.createClient(ProductService.class);
    }

    @Bean
    public OrderService orderService(WebClient webClient) {
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        return factory.createClient(OrderService.class);
    }

    @Bean
    public InventoryService inventoryService(WebClient webClient) {
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        return factory.createClient(InventoryService.class);
    }

    @Bean
    public PromotionService promotionService(WebClient webClient) {
        WebClientAdapter adapter = WebClientAdapter.create(webClient);
        HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
        return factory.createClient(PromotionService.class);
    }
}

// 关于配置和使用 HTTP 接口 参考官网 https://docs.springjava.cn/spring-framework/reference/integration/rest-clients.html#rest-http-interface
// Spring 框架允许您使用带 @HttpExchange 方法的 Java 接口来定义 HTTP 服务。您可以将此类接口传递给 HttpServiceProxyFactory 以创建代理，
// 该代理通过 HTTP 客户端（如 RestClient 或 WebClient）执行请求。您也可以从 @Controller 实现接口以进行服务器请求处理。